<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <script>
    // 阶段 1：JavaScript 核心能力
    const person = {
      name: '张三'
    };
    function fun(a, b, c, d) {
      // console.log(a, b, c, d);
      return a + b;
    }

    // 手写 call/apply/bind
    Function.prototype.myCall = function (thisArg, ...args) {
      // console.log('args', args);
      // 解决this指向问题(把当前this函数赋值给传入的对象的属性)，再调用该对象属性（传参），返回执行结果
      const fnSymbol = Symbol();
      thisArg[fnSymbol] = this;
      const result = thisArg[fnSymbol](...args);
      delete thisArg[fnSymbol];
      return result;
    };
    Function.prototype.myApply = function (thisArg, args) {
      // console.log('args', args);
      const fnSymbol = Symbol();
      thisArg[fnSymbol] = this;
      const result = thisArg[fnSymbol](...(args || []));
      delete thisArg[fnSymbol];
      return result;
    };
    Function.prototype.myBind = function (thisArg, ...args) {
      // thisArg = thisArg || globalThis;
      // 返回函数，该函数的返回值也是函数（该函数要修改this指向，并且合并传入的参数）
      return (...args2) => {
        return this.call(thisArg, ...args, ...args2);
      };
    };

    const rescall = fun.myCall(person, 'apply', 1);
    const resapply = fun.myApply(person, ['call', 2]);
    const bindFun = fun.myBind(person, 'bind', 2);
    const resBind = bindFun(3, 4);
    // console.log('resCall', resBind);
    // console.log('resApply', resBind);
    // console.log('resBind', resBind);

    // 手写 new 操作符

    // 手写 深拷贝（处理循环引用、Symbol、Map/Set）

    // 手写 防抖（debounce）与 节流（throttle）

    // 手写 数组扁平化（支持层级控制）

    // 手写 函数柯里化（currying）

    function throttae(params) {}

    throttae();
  </script>
  <body></body>
</html>
